package br.com.android.financas.fragments;

import java.sql.SQLException;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.Interval;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import br.com.android.financas.CategoriaTotal;
import br.com.android.financas.MesTotal;
import br.com.android.financas.R;
import br.com.android.financas.repositorio.RepositorioDespesa;
import br.com.android.financas.repositorio.RepositorioPoupanca;
import br.com.android.financas.repositorio.RepositorioReceita;
import br.com.android.financas.repositorio.impl.RepositorioDespesaImpl;
import br.com.android.financas.repositorio.impl.RepositorioPoupancaImpl;
import br.com.android.financas.repositorio.impl.RepositorioReceitaImpl;

import com.echo.holographlibrary.Bar;
import com.echo.holographlibrary.BarGraph;
import com.echo.holographlibrary.Line;
import com.echo.holographlibrary.LineGraph;
import com.echo.holographlibrary.LinePoint;
import com.echo.holographlibrary.PieGraph;
import com.echo.holographlibrary.PieGraph.OnSliceClickedListener;
import com.echo.holographlibrary.PieSlice;

public class HomeFrag extends Fragment{

	private RepositorioDespesa repositorioDespesa;
	private RepositorioReceita repositorioReceita;
	private RepositorioPoupanca repositorioPoupanca;

	private BarGraph barra;
	private PieGraph pie;
	private LineGraph grafico;
	private TextView nomeCategoria, campoTotalCategoria, campoTotalPercentual,labelMes,saldo;
	private double totalDespesas = 0;
	private double totalReceita = 0;
	private RelativeLayout layout;
	private boolean changed=false;
	private boolean first=false;
	private List<CategoriaTotal> categorias;
	private List<MesTotal> graficoDespesas;
	private Activity activity;
	private OnChangeListener mListener;
	private Date mesCorrente=new Date();
	private List<DateTime> mesesDisponiveis;
	private ProgressDialog progress;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		loadRepositorios(getActivity());

//		nomeCategoria = (TextView) getView().findViewById(R.id.home_categoriaNome);
//		campoTotalCategoria = (TextView) getView().findViewById(R.id.home_totalCategoria);
//		campoTotalPercentual = (TextView) getView().findViewById(R.id.home_totalPercentual);
		saldo = (TextView) getView().findViewById(R.id.home_saldo);
		labelMes = (TextView) getView().findViewById(R.id.home_mes);

		grafico = (LineGraph) getView().findViewById(R.id.home_graph);

		barra = (BarGraph) getView().findViewById(R.id.home_totalDespesa);
		pie = (PieGraph) getView().findViewById(R.id.home_piegraph);
		pie.setThickness(30);

		pie.setOnSliceClickedListener(new OnSliceClickedListener() {

			@Override
			public void onClick(int index) {
				onClickPie(index);
			}

		});

		barra.setHorizontal(true);

		layout= (RelativeLayout) getView().findViewById(R.id.homeLayout);
		HorizontalScrollView scroll= (HorizontalScrollView) getView().findViewById(R.id.home_scroll);
		grafico.setScroll(scroll);

		Button anterior=(Button)getView().findViewById(R.id.home_anterior);
		Button proximo=(Button)getView().findViewById(R.id.home_proximo);

		anterior.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				mesAnterior();
			}
		});

		proximo.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				proximoMes();
			}
		});

	}

	public void loadRepositorios(Activity activity){
		try {
			repositorioDespesa = new RepositorioDespesaImpl(activity);
			repositorioReceita = new RepositorioReceitaImpl(activity);
			repositorioPoupanca = new RepositorioPoupancaImpl(activity);

		} catch (SQLException e) {
		}
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.home, container, false);

		return view.findViewById(R.id.homeLayout);
	}

	public List<MesTotal> getGraficoDespesas() {
		if(graficoDespesas==null || changed)
			graficoDespesas = repositorioDespesa.getTotaisMensais((new DateTime((mesCorrente).getTime())).minusMonths(5).toDate(),mesCorrente);

		return graficoDespesas;
	}

	private void carregaGrafico() {
		grafico.removeAllLines();

		Line l = new Line();

		List<MesTotal> meses = getGraficoDespesas();
		Collections.sort(meses);

		int i = 0;

		if(meses.size()==1){
			LinePoint p = new LinePoint();

			p.setX(0);
			p.setY(0);
			p.setMes(null);
			l.addPoint(p);
			i+=100;
		}
		float max=0;
		for (MesTotal m : meses) {

			LinePoint p = new LinePoint();
			float total=(float) m.getTotal();
			if(max<total)
				max=total;
			p.setX(i);
			p.setY(total);
			p.setMes(m.getMes());
			l.addPoint(p);
			i += 100;
		}

		l.setColor(Color.parseColor("#FFBB33"));

		//int qt=(l.getPoints().size()%3)>0?(l.getPoints().size()/3)+1:(l.getPoints().size()/3);
		//grafico.getLayoutParams().width=(qt+1)*layout.getMeasuredWidth()-layout.getPaddingRight()-layout.getPaddingLeft();
		grafico.getLayoutParams().width=(int) (4096/2.5);
		grafico.addLine(l);
		//grafico.setRangeY(0, max);
		grafico.setLineToFill(0);

	}
	private boolean contem(DateTime data){
		if(mesesDisponiveis.size()>0){
			Interval intervalo= new Interval(mesesDisponiveis.get(0),mesesDisponiveis.get(mesesDisponiveis.size()-1));
			return intervalo.contains(data);
		}
		return false;

	}
	private void proximoMes(){
		DateTime novo=new DateTime(mesCorrente.getTime()).plusMonths(1).withTimeAtStartOfDay();
		if(contem(novo)){
			mesCorrente=novo.toDate();
			new Loading().execute();

		}

	}

	private void mesAnterior() {
		DateTime novo = new DateTime(mesCorrente.getTime()).minusMonths(1)
				.withTimeAtStartOfDay();
		if (contem(novo)) {
			mesCorrente = novo.toDate();
			new Loading().execute();
		}
	}

	private void addLine(PieSlice slice){
		Line l=new Line();
		l.setShowValueUpper(true);
		if(grafico.getLines().size()>1)
			grafico.getLines().remove(1);

		//Map<DateTime,Double> graficoDespesas = repositorioDespesa.getDespesasMensais((new DateTime((mesCorrente).getTime())).minusMonths(5).toDate(),mesCorrente,slice.getCategoriaTotal().getCategoria());
		List<MesTotal> graficoDespesas= repositorioDespesa.getTotaisMensais((new DateTime((mesCorrente).getTime())).minusMonths(5).toDate(),mesCorrente,slice.getCategoriaTotal().getCategoria());

		//List<DateTime> meses = new ArrayList<DateTime>(graficoDespesas.keySet());
		Collections.sort(graficoDespesas);

		if(grafico.getLines().size()>0){
			Line linha= grafico.getLine(0);

			int i = 0;

			if(graficoDespesas.size()==1){
				LinePoint p = new LinePoint();

				p.setX(0);
				p.setY(0);
				p.setMes(null);
				l.addPoint(p);
				i+=100;
			}
			float max=0;
			for(LinePoint ponto: linha.getPoints()){

				for (MesTotal m : graficoDespesas) {
					if(m.getMes().equals(ponto.getMes())){
						LinePoint p = new LinePoint();
						float total=(float) m.getTotal();
						if(max<total)
							max=total;
						p.setX(ponto.getX());
						p.setY(total);
						p.setMes(m.getMes());
						l.addPoint(p);
					}
				}

			}

			l.setColor(slice.getColor());
			grafico.addLine(l);
		}


	}

	public void carregaBarras(double totalDespesa, double totalReceita) {

		barra.clearBars();

		Bar despesa = new Bar();
		despesa.setColor(Color.parseColor("#FF0000"));
		despesa.setName(getActivity().getString(R.string.despesas));
		despesa.setValue((float) totalDespesa);

		Bar receita = new Bar();
		receita.setColor(Color.parseColor("#008000"));
		receita.setName(getActivity().getString(R.string.receitas));
		receita.setValue((float) totalReceita);

		ArrayList<Bar> points = new ArrayList<Bar>();
		points.add(despesa);
		points.add(receita);
		barra.setBars(points);
		barra.setShouldUpdate(true);

	}

	private void carregaPie() {
		pie.removeSlices();

		List<CategoriaTotal> categorias = getCategorias();

		for (CategoriaTotal categoria : categorias) {
			PieSlice slice = new PieSlice();
			slice.setColor(categoria.getCategoria().getCor());

			slice.setValue((float) categoria.getTotal());
			slice.setTitle(categoria.getCategoria().getNome());
			slice.setCategoriaTotal(categoria);
			pie.addSlice(slice);
		}
		if(categorias.size()>0){
			pie.setFirtSelectedIndex();
			onClickPie(pie.getIndexSelected());
		}
	}

	public List<CategoriaTotal> getCategorias() {
		if(categorias==null || changed)
			categorias = repositorioDespesa.getCategoriasTotal(mesCorrente);
		return categorias;
	}

	public void loadData(){

		getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
				carregaBarras(getTotalDespesas(), getTotalReceita());
			}
		});

		getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
				carregaPie();
			}
		});

		getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
				carregaGrafico();
			}
		});

		labelMes.setText(new SimpleDateFormat("MMMM").format(mesCorrente));

		saldo.setText(NumberFormat.getCurrencyInstance().format(getTotalReceita()-getTotalDespesas()));
		if(getTotalReceita()>=getTotalDespesas())
			saldo.setTextColor(Color.parseColor("#008000"));
		else
			saldo.setTextColor(Color.parseColor("#FF0000"));

	}

	public void load(Activity activity){
		loadRepositorios(activity);

		totalReceita=0;
		totalDespesas=0;
		categorias=null;
		graficoDespesas=null;
		mesesDisponiveis=null;

		new Thread(new Runnable() {
			@Override
			public void run() {

				getTotalReceita();
			}
		}).start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				getTotalDespesas();
			}
		}).start();


		new Thread(new Runnable() {
			@Override
			public void run() {
				getCategorias();
			}
		}).start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				getGraficoDespesas();
			}
		}).start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				getMesesDisponiveis();
			}
		}).start();

		changed=false;

	}

	@Override
	public void onResume() {
		super.onResume();
		getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
				loadData();
			}
		});

	}

	public List<DateTime> getMesesDisponiveis() {
		if(mesesDisponiveis==null || changed)
			mesesDisponiveis=repositorioDespesa.getMeses();
		return mesesDisponiveis;
	}

	public double getTotalDespesas() {
		if(totalDespesas==0 || changed)
			totalDespesas = repositorioDespesa.getTotal(mesCorrente)+repositorioPoupanca.getTotalDespesa(mesCorrente);
		return totalDespesas;
	}
	public double getTotalReceita() {
		if(totalReceita==0 || changed){
			totalReceita = repositorioReceita.getTotal(mesCorrente);
		}
		return totalReceita;
	}

	private void onClickPie(int index){
		PieSlice slice = pie.getSlice(index);

		/*nomeCategoria.setText(slice.getTitle());
		nomeCategoria.setTextColor(slice.getCategoriaTotal().getCategoria().getCor());

		double totalCategoria = slice.getCategoriaTotal().getTotal();
		double percentual = totalDespesas > 0 ? (totalCategoria)
				/ totalDespesas : 0;

		campoTotalCategoria.setText(NumberFormat.getCurrencyInstance()
				.format(totalCategoria));
		campoTotalPercentual.setText(NumberFormat.getPercentInstance()
				.format(percentual));*/

		addLine(slice);
	}

	public void setProgress(ProgressDialog progress) {
		this.progress = progress;
	}

	public void setChanged(boolean changed) {
		this.changed = changed;
	}

	public void setFirst(boolean first) {
		this.first = first;
	}
	public void setActivity(Activity activity) {
		this.activity = activity;
	}

	public void onAttach(Activity activity) {
	    try {
	    	super.onAttach(activity);
	        this.mListener = (OnChangeListener)activity;

	    }
	    catch (final ClassCastException e) {
	        throw new ClassCastException(activity.toString() + " must implement OnChangeListener");
	    }
	}


	private class Loading extends AsyncTask<String, String, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			changed=true;
			load(activity);

			return true;
		}
		 @Override
	      protected void onPreExecute() {
			  progress = new ProgressDialog(getActivity());
	          //Cria novo um ProgressDialogo e exibe
	          progress.setMessage(activity.getString(R.string.aguarde));
	          progress.setCancelable(false);
	          progress.show();
	      }
		 @Override
	      protected void onPostExecute(Boolean result) {
			 loadData();
			 progress.hide();
		 }
	}

}
